{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "name": "predictit-clean-sweep.ipynb",
      "provenance": [],
      "collapsed_sections": []
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    }
  },
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "jZZyH7El-IT9",
        "colab_type": "text"
      },
      "source": [
        "In this example, we use the PredictIt odds of democrats winning the house, senate, and presidency to make a prediction on whether they will sweep all three.\n",
        "\n",
        "PredictIt is composed of markets, which in turn are composed of questions. Although a PredictIt market has a literal question as its name, for consistency with Metaculus and Foretold, ergo considers each option in a market to be a separate \"question\". \n",
        "\n",
        "For instance, in the PredictIt market \"Which party will win the 2020 U.S. presidential election?\", one such question would be the democrat option. This is a binary question that essentially asks \"will democrats win the 2020 U.S. presidential election\".\n",
        "\n",
        "One thing to keep in mind is that the 10% profit fee, 5% withdrawal fee, and $850 betting cap are known to decrease the efficiency of markets. Long shot bets tend to be inflated while safer bets with lower margins are deflated. They also inflate prices in markets with linked outcomes, resulting in situations where adding up the prices of each contract comes to over $1."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "I9sieYAtOvMz",
        "colab_type": "text"
      },
      "source": [
        "##SETUP"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "lJlJ76CoKOTp",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 660
        },
        "outputId": "5e3d6aca-7edf-46c9-8e21-41c71dc1d873"
      },
      "source": [
        "!pip install --progress-bar off --quiet poetry\n",
        "!pip install --progress-bar off --quiet git+https://github.com/oughtinc/ergo.git#egg=ergo[notebooks]"
      ],
      "execution_count": 1,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "\u001b[?25l\n",
            "\u001b[?25h\u001b[?25l\n",
            "\u001b[?25h\u001b[?25l\n",
            "\u001b[?25h\u001b[?25l\n",
            "\u001b[?25h\u001b[?25l\n",
            "\u001b[?25h\u001b[?25l\n",
            "\u001b[?25h  Building wheel for pyrsistent (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
            "  Installing build dependencies ... \u001b[?25l\u001b[?25hdone\n",
            "  Getting requirements to build wheel ... \u001b[?25l\u001b[?25hdone\n",
            "    Preparing wheel metadata ... \u001b[?25l\u001b[?25hdone\n",
            "\u001b[?25l\n",
            "\u001b[?25h\u001b[?25l\n",
            "\u001b[?25h\u001b[?25l\n",
            "\u001b[?25h\u001b[?25l\n",
            "\u001b[?25h\u001b[?25l\n",
            "\u001b[?25h\u001b[?25l\n",
            "\u001b[?25h\u001b[?25l\n",
            "\u001b[?25h\u001b[?25l\n",
            "\u001b[?25h\u001b[?25l\n",
            "\u001b[?25h\u001b[?25l\n",
            "\u001b[?25h\u001b[?25l\n",
            "\u001b[?25h\u001b[?25l\n",
            "\u001b[?25h\u001b[?25l\n",
            "\u001b[?25h\u001b[?25l\n",
            "\u001b[?25h\u001b[?25l\n",
            "\u001b[?25h\u001b[?25l\n",
            "\u001b[?25h\u001b[?25l\n",
            "\u001b[?25h  Building wheel for ergo (PEP 517) ... \u001b[?25l\u001b[?25hdone\n",
            "  Building wheel for country-converter (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
            "  Building wheel for numpyro (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
            "  Building wheel for python-Levenshtein (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
            "  Building wheel for typing (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
            "\u001b[31mERROR: google-colab 1.0.0 has requirement requests~=2.23.0, but you'll have requests 2.21.0 which is incompatible.\u001b[0m\n",
            "\u001b[31mERROR: datascience 0.10.6 has requirement folium==0.2.1, but you'll have folium 0.8.3 which is incompatible.\u001b[0m\n",
            "\u001b[31mERROR: albumentations 0.1.12 has requirement imgaug<0.2.7,>=0.2.5, but you'll have imgaug 0.2.9 which is incompatible.\u001b[0m\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "MGHry-zC68jP",
        "colab_type": "text"
      },
      "source": [
        "# Code\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Fu_S10K-7tp8",
        "colab_type": "text"
      },
      "source": [
        "Import the required packages."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "3nqWcuKa69BE",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 90
        },
        "outputId": "175f3a20-0fdd-4207-ac19-a50634d01f62"
      },
      "source": [
        "import ergo\n",
        "from ergo.contrib.predictit.fuzzy_search import search_market, search_question"
      ],
      "execution_count": 2,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "/usr/local/lib/python3.6/dist-packages/ergo/ppl.py:15: TqdmExperimentalWarning: Using `tqdm.autonotebook.tqdm` in notebook mode. Use `tqdm.tqdm` instead to force console mode (e.g. in jupyter console)\n",
            "  from tqdm.autonotebook import tqdm\n",
            "/usr/local/lib/python3.6/dist-packages/statsmodels/tools/_testing.py:19: FutureWarning: pandas.util.testing is deprecated. Use the functions in the public API at pandas.testing instead.\n",
            "  import pandas.util.testing as tm\n"
          ],
          "name": "stderr"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "03VbeFAu7wZz",
        "colab_type": "text"
      },
      "source": [
        "Create an instance of a PredictIt scraper."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "eeejoSF77Vgh",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "pi = ergo.PredictIt()"
      ],
      "execution_count": 3,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "vOMtNFQV73zd",
        "colab_type": "text"
      },
      "source": [
        "Search for the markets."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "_P-SvHLR7qX0",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "m_senate = search_market(pi,  \"party control senate\")\n",
        "m_house = search_market(pi, \"party control house\")\n",
        "m_pres = search_market(pi, \"party win pres\")"
      ],
      "execution_count": 4,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "PJZKregf8kSR",
        "colab_type": "text"
      },
      "source": [
        "Print the market names to ensure we found the right ones."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "uY9M9WKG8BZE",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 72
        },
        "outputId": "635af997-7138-4eee-ab7d-1beb448ff326"
      },
      "source": [
        "print(\"Senate: \" + m_senate.name)\n",
        "print(\"House: \" + m_house.name)\n",
        "print(\"Pres: \" + m_pres.name)"
      ],
      "execution_count": 5,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "Senate: Which party will control the Senate after 2020 election?\n",
            "House: Which party will control the House after 2020 election?\n",
            "Pres: Which party will win the 2020 U.S. presidential election?\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "yy9N_Bwx9feQ",
        "colab_type": "text"
      },
      "source": [
        "Search for the democrat question."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "TwfIDL859jJK",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "q_senate = search_question(m_senate, \"dem\")\n",
        "q_house = search_question(m_house, \"dem\")\n",
        "q_pres = search_question(m_pres, \"dem\")\n"
      ],
      "execution_count": 6,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "onwEAOOL91OY",
        "colab_type": "text"
      },
      "source": [
        "Print the contract names to ensure we found the right ones."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "UsB9SAmc9rxB",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 72
        },
        "outputId": "6c7a49be-796f-4c31-b844-86cb85f8d6df"
      },
      "source": [
        "print(\"Senate: \" + q_senate.name)\n",
        "print(\"House: \" + q_house.name)\n",
        "print(\"Pres: \" + q_pres.name)"
      ],
      "execution_count": 7,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "Senate: Democratic\n",
            "House: Democratic\n",
            "Pres: Democratic\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "-H4iCxMIAPLP",
        "colab_type": "text"
      },
      "source": [
        "Multiply the odds of the respective questions to predict the odds of a clean sweep."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "p04YZelVAON5",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 35
        },
        "outputId": "59dd30c4-ceb5-424c-fa45-b9ff1271290c"
      },
      "source": [
        "clean_sweep = q_senate.lastTradePrice * q_house.lastTradePrice * q_pres.lastTradePrice\n",
        "print(\"Based on these three markets, the odds of a democratic clean sweep is \" + str(round(clean_sweep * 100, 2)) + \"%\")"
      ],
      "execution_count": 8,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "Based on these three markets, the odds of a democratic clean sweep is 30.39%\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "_E_Xt8hKA72_",
        "colab_type": "text"
      },
      "source": [
        "Interestingly enough, this is much lower than the odds of a sweep in the specific clean sweep market. This makes sense, as the three markets are highly correlated."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "fyGnBfXVAiNB",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 54
        },
        "outputId": "0b1e1431-898d-4cf9-89ad-40ad943f12a3"
      },
      "source": [
        "m_sweep = search_market(pi, \"dem clean sweep\")\n",
        "print(m_sweep.name)\n",
        "# Since this market only contains a single question, we can find it by getting the first element from a list of all the questions.\n",
        "q_sweep = list(m_sweep.questions)[0]\n",
        "print(str(q_sweep.lastTradePrice * 100) + \"%\")"
      ],
      "execution_count": 9,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "Will Democrats win the White House, Senate and House in 2020?\n",
            "52.0%\n"
          ],
          "name": "stdout"
        }
      ]
    }
  ]
}